From 9ffb9a37b3679d40e5e566649166acbddab34830 Mon Sep 17 00:00:00 2001 From: "robertlipe@gmail.com" Date: Tue, 27 Nov 2012 01:53:48 +0000 Subject: [PATCH] Jeremy Mortis adds support for MTK Locus class of receivers. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@4207 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/Makefile.in | 1 + gpsbabel/mtk_locus.c | 615 ++++++++++++++++++ gpsbabel/reference/mtk_locus.gpx | 124 ++++ gpsbabel/reference/mtk_locus.nmea | 16 + gpsbabel/testo.d/mtk_locus.test | 9 + gpsbabel/vecs.c | 7 + .../formats/options/mtk_locus-baudrate.xml | 2 + .../formats/options/mtk_locus-download.xml | 5 + .../formats/options/mtk_locus-enable.xml | 2 + .../formats/options/mtk_locus-erase.xml | 2 + .../formats/options/mtk_locus-status.xml | 2 + 11 files changed, 785 insertions(+) create mode 100644 gpsbabel/mtk_locus.c create mode 100644 gpsbabel/reference/mtk_locus.gpx create mode 100644 gpsbabel/reference/mtk_locus.nmea create mode 100755 gpsbabel/testo.d/mtk_locus.test create mode 100644 gpsbabel/xmldoc/formats/options/mtk_locus-baudrate.xml create mode 100644 gpsbabel/xmldoc/formats/options/mtk_locus-download.xml create mode 100644 gpsbabel/xmldoc/formats/options/mtk_locus-enable.xml create mode 100644 gpsbabel/xmldoc/formats/options/mtk_locus-erase.xml create mode 100644 gpsbabel/xmldoc/formats/options/mtk_locus-status.xml diff --git a/gpsbabel/Makefile.in b/gpsbabel/Makefile.in index 1fbfbe6bc..81a12b90d 100644 --- a/gpsbabel/Makefile.in +++ b/gpsbabel/Makefile.in @@ -66,6 +66,7 @@ ALL_FMTS=$(MINIMAL_FMTS) gtm.o gpsutil.o pcx.o cetus.o copilot.o \ pocketfms_bc.o pocketfms_fp.o pocketfms_wp.o naviguide.o enigma.o \ vpl.o teletype.o jogmap.o bushnell.o bushnell_trl.o wintec_tes.o \ subrip.o garmin_xt.o explorist_ini.o garmin_fit.o lowranceusr4.o \ + mtk_locus.o FMTS=@FMTS@ diff --git a/gpsbabel/mtk_locus.c b/gpsbabel/mtk_locus.c new file mode 100644 index 000000000..ca9fdaad1 --- /dev/null +++ b/gpsbabel/mtk_locus.c @@ -0,0 +1,615 @@ +/* + +Format converter for MediaTek Locus-capable devices. + +Copyright (C) 2012 Jeremy Mortis, mortis@tansay.ca + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +------------------------------------------------------------------- + +This module will download logged track data (a.k.a. Locus) from a GPS +devices based on the MediaTek MT3339 GPS chipset, such as: +- GlobalTop PA6H Module +- Fastrax IT530 + +The MT3339 also emits standard NMEA packets including +$GPGGA, $GPGSA, $GPGSV, $GPRMC, and $GPVTG. This module ignores those. +If you have an MT3339 and you want to process NMEA packets, simply use +the nmea format instead of this one. + +Example usage:: +# Read from USB port, output trackpoints in GPX format +./gpsbabel -t -i mtk_locus -f /dev/ttyUSB0 -o gpx -F out.gpx + +*/ + +#include +#include +#include + +#include "defs.h" +#include "gbser.h" + +static route_head* track; + +static char* opt_baudrate; +static char* opt_download; +static char* opt_erase; +static char* opt_status; +static char* opt_enable; + +arglist_t mtk_locus_args[] = { + {"baudrate", &opt_baudrate, "Speed in bits per second of serial port (autodetect=0)", "0", ARGTYPE_INT, ARG_NOMINMAX }, + {"download", &opt_download, "Download logged fixes", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"erase", &opt_erase, "Erase device data after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"status", &opt_status, "Show device status", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"enable", &opt_enable, "Enable logging after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR +}; + +static void mtk_locus_rd_init(const char* fname); +static void mtk_locus_rd_deinit(void); +static void mtk_locus_read(void); + +ff_vecs_t mtk_locus_vecs = { + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + mtk_locus_rd_init, + NULL, // write init + mtk_locus_rd_deinit, + NULL, // write deinit + mtk_locus_read, + NULL, // write + NULL, // exit + mtk_locus_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ +}; + +#define MYNAME "mtk_locus" +#define TIMEOUT 1500 + +#define PMTK_ACK "$PMTK001" +#define PMTK_LOCUS_STOP_LOGGER "$PMTK185" +#define PMTK_LOCUS_QUERY_STATUS "$PMTK183" +#define PMTK_LOCUS_ERASE_FLASH "$PMTK184" +#define PMTK_Q_LOCUS_DATA "$PMTK622" +#define PMTK_Q_RELEASE "$PMTK605" +#define PMTK_DT_RELEASE "$PMTK705" + +static void* fd; +static enum {rm_serial, rm_file} read_mode; +static int packetnum; +static char line[1000]; +static int download_complete; +static int valid_packet_found; +static int fixes_found; +static int first_loxsequence; +static int last_loxsequence; +static char waiting_for[20]; + + +static void set_baudrate(void); +static void read_line(void); +static void process_packet(void); +static void process_pmtklox(void); +static void process_pmtklog(void); +static void process_pmtk001(void); +static void process_pmtk705(void); +static void send_command(char* s, char* waitfor); +static int calculate_checksum(char* s, int length); +static void dbg(int l, const char* msg, ...); + +static void +mtk_locus_rd_init(const char* fname) +{ + dbg(1, "Opening file: %s\n", fname); + + if (gbser_is_serial(fname)) { + + dbg(1, "Input is a serial port\n"); + read_mode = rm_serial; + if ((fd = gbser_init(fname)) == NULL) { + fatal(MYNAME ": Can't initialise port \"%s\" (%s)\n", fname, strerror(errno)); + } + set_baudrate(); + gbser_flush(fd); + + } else { + + dbg(1, "Input is a normal file\n"); + read_mode = rm_file; + if ((fd = gbfopen(fname, "rb", MYNAME)) == NULL) { + fatal(MYNAME ": Can't initialise port \"%s\" (%s)\n", fname, strerror(errno)); + } + } + + dbg(1, "File opened\n"); +} + +static void +mtk_locus_rd_deinit(void) +{ + if (read_mode == rm_serial) { + gbser_deinit(fd); + } else { + gbfclose(fd); + } +} + +static void +mtk_locus_read(void) +{ + int i; + + track = route_head_alloc(); + track_add_head(track); + dbg(1, "Track initialized\n"); + + packetnum = 0; + valid_packet_found = 0; + fixes_found = 0; + download_complete = 0; + first_loxsequence = -1; + last_loxsequence = -1; + + read_line(); + // initial serial buffer may contain garbage, so read until valid packet found + for (i=0; i<10; i++) { + process_packet(); + read_line(); + if (valid_packet_found) { + break; + } + } + + if (! valid_packet_found) { + fatal(MYNAME "No valid input data found"); + } + + if (strcmp(opt_download, "1") == 0) { + send_command(PMTK_Q_LOCUS_DATA ",1", NULL); + + while (! download_complete) { + process_packet(); + read_line(); + } + } + + if (read_mode == rm_serial) { + if (strcmp(opt_erase, "1") == 0) { + send_command(PMTK_LOCUS_ERASE_FLASH ",1", PMTK_ACK); + printf("Flash erased\n"); + } + + if (strcmp(opt_enable, "1") == 0) { + send_command(PMTK_LOCUS_STOP_LOGGER ",0", PMTK_ACK); + printf("Logging enabled\n"); + } else { + send_command(PMTK_LOCUS_STOP_LOGGER ",1", PMTK_ACK); + printf("Logging disabled\n"); + } + + if (strcmp(opt_status, "1") == 0) { + printf("Device status:\n"); + send_command(PMTK_Q_RELEASE, PMTK_DT_RELEASE); + send_command(PMTK_LOCUS_QUERY_STATUS, PMTK_ACK); + } + } +} + +void +set_baudrate() +{ + int i; + int rc; + int baudrates[] = { 4800, 9600, 14400, 19200, 38400, 57600, 115200, 0 }; + int baudrate; + + if (strcmp(opt_baudrate, "0") != 0) { + + baudrate = atoi(opt_baudrate); + rc = gbser_set_speed(fd, baudrate); + if (rc != gbser_OK) { + fatal(MYNAME ": Set baud rate to %i failed (%i)\n", baudrate, rc); + } + + } else { + + dbg(1, "Probing for baudrate...\n"); + for (i=0;; i++) { + baudrate = baudrates[i]; + if (baudrate == 0) { + fatal(MYNAME ": Autobaud connection failed\n"); + } + dbg(1, MYNAME ": Probing at %i baud...\n", baudrate); + rc = gbser_set_speed(fd, baudrate); + + if (rc != gbser_OK) { + dbg(1, "Set speed failed\n"); + continue; + } + + rc = gbser_read_line(fd, line, sizeof(line)-1, TIMEOUT, 0x0A, 0x0D); + if (rc != gbser_OK) { + dbg(1, "Read test failed\n"); + continue; + } + + dbg(1, "Port successfully opened\n"); + break; + } + } +} + +void +read_line(void) +{ + int rc; + char* s; + + line[0] = '\0'; + + if (read_mode == rm_file) { + s = gbfgetstr(fd); + if (s == NULL) { + dbg(1, "EOF reached\n"); + download_complete = 1; + return; + } + strncat(line, s, sizeof(line)-1); + } else { + rc = gbser_read_line(fd, line, sizeof(line)-1, TIMEOUT, 0x0A, 0x0D); + if (rc != gbser_OK) { + fatal(MYNAME "Serial read failed: %i\n", rc); + } + } + + packetnum++; + dbg(1, "Line %i: %s\n", packetnum, line); + return; +} + +void +process_packet() +{ + + int calculated_checksum; + int given_checksum; + + if ((strlen(line) < 3) || (line[0] != '$') || (line[strlen(line)-3] != '*')) { + dbg(1, "Line %i: Malformed packet\n", packetnum); + return; + } + + calculated_checksum = calculate_checksum(&line[1], strlen(line) - 1 - 3); + sscanf(&line[strlen(line) - 2], "%02x", &given_checksum); + if (calculated_checksum != given_checksum) { + dbg(1, "Line %i: NMEA Checksum incorrect, expecting %02X\n", packetnum, calculated_checksum); + return; + } + + if (strncmp(line, waiting_for, strlen(waiting_for)) == 0) { + waiting_for[0] = '\0'; + } + + valid_packet_found = 1; + line[strlen(line) - 3] = '\0'; // remove checksum + + // note that use of strtok in following routines corrupts the value of line + + if (strncmp(line, "$PMTKLOX", 8) == 0) { + process_pmtklox(); + } else if (strncmp(line, "$PMTKLOG", 8) == 0) { + process_pmtklog(); + } else if (strncmp(line, "$PMTK001", 8) == 0) { + process_pmtk001(); + } else if (strncmp(line, "$PMTK705", 8) == 0) { + process_pmtk705(); + } else { + dbg(1, "Unknown packet type\n"); + } + +} + +void +process_pmtklox() +{ + + char* token; + char* loxtype; + int loxsequence; + uint32_t timestamp; + char fixtype; + float latitude; + float longitude; + int height; + uint8_t calculated_checksum; + int hexval; + uint8_t fixbytes[16]; + int i; + int wordnum; + int bytenum; + int fixnum; + static waypoint* trkpt; + static waypoint* waypt; + + token = strtok(line, ","); + if ((token == NULL) || (strcmp(token, "$PMTKLOX") != 0)) { + warning("Line %i: Invalid packet id\n", packetnum); + return; + } + + loxtype = strtok(NULL, ","); + if (loxtype == NULL) { + warning("Line %i: Missing lox type\n", packetnum); + return; + } + + if (strcmp(loxtype, "0") == 0) { + last_loxsequence = atoi(strtok(NULL, "*")) - 1; + dbg(1, "Line %i: last sequence will be %i\n", packetnum, last_loxsequence); + return; + } + + if (strcmp(loxtype, "2") == 0) { + printf("Found %i fixes\n", fixes_found); + download_complete = 1; + return; + } + + if (strcmp(loxtype, "1") != 0) { + dbg(1, "Line %i: Invalid lox type\n", packetnum); + return; + } + + loxsequence = atoi(strtok(NULL, ",")); + + if (first_loxsequence == -1) { + first_loxsequence = loxsequence; + if (first_loxsequence != 0) { + fatal(MYNAME "Dump already in progress (first $PMTKLOX has sequence %i)\n", first_loxsequence); + } + } + + if (read_mode == rm_serial) { + printf("Downloading packet %i of %i\r", loxsequence, last_loxsequence); + } + + token = strtok(NULL, ","); + fixnum = 0; + while (token != NULL) { + fixnum++; + bytenum = 0; + calculated_checksum = 0; + for (wordnum=0; wordnum<4; wordnum++) { // 4 8-byte hex strings per fix + if (token == NULL) { + dbg(1, "Line %i: Fix %i incomplete data\n", packetnum, fixnum); + return; + } + for (i=0; i<4; i++) { + sscanf(&token[i * 2], "%2x", &hexval); + fixbytes[bytenum++] = hexval; + calculated_checksum ^= hexval; + } + token = strtok(NULL, ","); + } + + if (calculated_checksum != 0) { + dbg(1, "Line %i: Fix %i failed checksum\n", packetnum, fixnum); + continue; + } + + timestamp = le_read32(&fixbytes[0]); + fixtype = fixbytes[4]; + latitude = le_read_float(&fixbytes[5]); + longitude = le_read_float(&fixbytes[9]); + height = le_read16(&fixbytes[13]); + + if (fixtype != '\x02') { + dbg(1, "line %i: Fix %i Invalid fix type: %02X\n", packetnum, fixnum, fixtype); + continue; + } + + if ((latitude < -180.0) || (latitude > 180.0) + || (longitude < -180.0) || (longitude > 180.0) + || (height < -1000) || (height > 100000)) { + dbg(1, "line %i: Fix %i data out of range\n", packetnum, fixnum); + continue; + } + + if (global_opts.masked_objective & TRKDATAMASK) { + trkpt = waypt_new(); + trkpt->creation_time = timestamp; + trkpt->microseconds = 0; + trkpt->latitude = latitude; + trkpt->longitude = longitude; + trkpt->altitude = height; + trkpt->sat = 0; + trkpt->hdop = 0; + trkpt->fix = fix_3d; + track_add_wpt(track, trkpt); + } + + if (global_opts.masked_objective & WPTDATAMASK) { + waypt = waypt_new(); + waypt->creation_time = timestamp; + waypt->microseconds = 0; + waypt->latitude = latitude; + waypt->longitude = longitude; + waypt->altitude = height; + waypt->sat = 0; + waypt->hdop = 0; + waypt->fix = fix_3d; + waypt_add(waypt); + } + + dbg(1, "Time: %li Type: %02x Lat: %f Long: %f height: %i\n", (long int)timestamp, fixtype, latitude, longitude, height); + + fixes_found++; + } +} + +void +process_pmtklog() +{ + int status; + int type; + + strtok(line, ","); + + printf("Serial#: %s\n", strtok(NULL, ",")); + + type = atoi(strtok(NULL, ",")); + if (type == 0) { + printf("Type: %i (wrap around when full)\n", type); + } else { + printf("Type: %i (stop when full)\n", type); + } + + printf("Mode: 0x%02X\n", atoi(strtok(NULL, ","))); + printf("Content: %s\n", strtok(NULL, ",")); + printf("Interval: %s seconds\n", strtok(NULL, ",")); + printf("Distance: %s\n", strtok(NULL, ",")); + printf("Speed: %s\n", strtok(NULL, ",")); + + status = atoi(strtok(NULL, ",")); + if (status == 0) { + printf("Status: %i (enabled)\n", status); + } else { + printf("Status: %i (disabled)\n", status); + } + + printf("Number: %s fixes available\n", strtok(NULL, ",")); + printf("Percent: %s%% used\n", strtok(NULL, ",")); +} + +void +process_pmtk001() +{ + char* cmd; + char* flag; + + strtok(line, ","); + cmd = strtok(NULL,","); + flag = strtok(NULL,","); + + switch (atoi(flag)) { + case 0: + dbg(1, "Ack: %s %s (Invalid command)\n", cmd, flag); + break; + case 1: + dbg(1, "Ack: %s %s (Unsupported command)\n", cmd, flag); + break; + case 2: + dbg(1, "Ack: %s %s (Action failed)\n", cmd, flag); + break; + case 3: + dbg(1, "Ack: %s %s (Success)\n", cmd, flag); + break; + default: + dbg(1, "Ack: %s %s (Unknown error)\n", cmd, flag); + break; + } +} + +void +process_pmtk705() +{ + char* token; + + token = strtok(line, ","); + token = strtok(NULL,","); + + printf("Firmware: %s\n", token); +} + +void +send_command(char* s, char* wait_for) +{ + int rc; + time_t starttime; + time_t currtime; + char cmd[100]; + int checksum; + + if (read_mode == rm_file) { + dbg(1, "Sending device commands ignored when using file input: %s\n", s); + return; + } + + checksum = calculate_checksum(&s[1], strlen(s)-1); + snprintf(cmd, sizeof(cmd)-1, "%s*%02X\r\n", s, checksum); + + rc = gbser_print(fd, cmd); + if (rc != gbser_OK) { + fatal(MYNAME ": Write error (%d)\n", rc); + } + + dbg(1, "Sent command: %s\n", cmd); + + if (wait_for == NULL) { + waiting_for[0] = '\0'; + return; + } + + time(&starttime); + cmd[0] = '\0'; + strncat(cmd, &s[5], 3); + waiting_for[0] = '\0'; + strncat(waiting_for, wait_for, sizeof(waiting_for)-1); + dbg(1, "Waiting for: %s\n", waiting_for); + + read_line(); + while (strlen(waiting_for) > 0) { + time(&currtime); + if (currtime > starttime + 5) { + fatal(MYNAME "Ack not received: %s\n", s); + } + process_packet(); + read_line(); + } +} + +int +calculate_checksum(char* s, int length) +{ + int i; + int sum; + sum = 0; + + for (i=0; i= l) { + vfprintf(stderr,msg, ap); + fflush(stderr); + } + va_end(ap); +} + + diff --git a/gpsbabel/reference/mtk_locus.gpx b/gpsbabel/reference/mtk_locus.gpx new file mode 100644 index 000000000..d15ddab41 --- /dev/null +++ b/gpsbabel/reference/mtk_locus.gpx @@ -0,0 +1,124 @@ + + + + + + 1117.000000 + + WPT001 + WPT001 + WPT001 + 3d + + + 1116.000000 + + WPT002 + WPT002 + WPT002 + 3d + + + 1115.000000 + + WPT003 + WPT003 + WPT003 + 3d + + + 1115.000000 + + WPT004 + WPT004 + WPT004 + 3d + + + 1114.000000 + + WPT005 + WPT005 + WPT005 + 3d + + + 1112.000000 + + WPT006 + WPT006 + WPT006 + 3d + + + 1111.000000 + + WPT007 + WPT007 + WPT007 + 3d + + + 1108.000000 + + WPT008 + WPT008 + WPT008 + 3d + + + 1106.000000 + + WPT009 + WPT009 + WPT009 + 3d + + + 1106.000000 + + WPT010 + WPT010 + WPT010 + 3d + + + 1104.000000 + + WPT011 + WPT011 + WPT011 + 3d + + + 1103.000000 + + WPT012 + WPT012 + WPT012 + 3d + + + 1101.000000 + + WPT013 + WPT013 + WPT013 + 3d + + + 1097.000000 + + WPT014 + WPT014 + WPT014 + 3d + + + + diff --git a/gpsbabel/reference/mtk_locus.nmea b/gpsbabel/reference/mtk_locus.nmea new file mode 100644 index 000000000..520e196ac --- /dev/null +++ b/gpsbabel/reference/mtk_locus.nmea @@ -0,0 +1,16 @@ +blah7.000,A,5103.6616,N,11407.4451,W,0.63,333.96,261012,,,A*7D +$GPVTG,333.96,T,,M,0.63,N,1.17,K,A*33 +$PGTOP,11,2*6E +$GPGGA,192518.000,5103.6617,N,11407.4452,W,1,8,1.10,1091.7,M,-17.5,M,,*55 +$GPGSA,A,3,05,10,29,02,25,04,12,31,,,,,2.08,1.10,1.76*07 +$GPRMC,192518.000,A,5103.6617,N,11407.4452,W,0.38,333.96,261012,,,A*7E +$GPVTG,333.96,T,,M,0.38,N,0.71,K,A*3C +$PMTKLOX,0,3*5A +$PMTKLOX,1,0,0100010A,1F000000,0F000000,0000100A,00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000001F,FFFFFFFF,FFFFFFFF,FFFFFFFF,000C8C14,4FD08A50,029E3E4C,42853FE4,C25D042C,5ED08A50,02B03E4C,42903FE4,C25C0407*5B +$PMTKLOX,1,1,6DD08A50,02BC3E4C,42973FE4,C25B0438,7CD08A50,02B93E4C,42933FE4,C25B0428,8BD08A50,02BC3E4C,42943FE4,C25A04DC,9AD08A50,02B73E4C,42903FE4,C25804C0,A9D08A50,02AA3E4C,42883FE4,C25704F9,B8D08A50,029E3E4C,42843FE4,C25404D3*26 +$PMTKLOX,1,2,C7D08A50,02983E4C,42843FE4,C25204AC,D6D08A50,02973E4C,42853FE4,C25204B3,E5D08A50,02983E4C,428D3FE4,C2500485,F4D08A50,02943E4C,428C3FE4,C24F0486,03D18A50,02983E4C,42863FE4,C24D0474,12D18A50,02AB3E4C,42783FE4,C24904AC*23 +$PMTKLOX,2*47 +$PGTOP,11,2*6E +$GPGGA,192539.000,5103.6648,N,11407.4450,W,1,8,1.10,1092.1,M,-17.5,M,,*5B +$GPGSA,A,3,05,10,29,02,25,04,12,31,,,,,2.08,1.10,1.77*06 +$GPGSV,3,1,11,02,75,084,31,12,63,194,21,25,58,284,26,10,41,083,21*70 diff --git a/gpsbabel/testo.d/mtk_locus.test b/gpsbabel/testo.d/mtk_locus.test new file mode 100755 index 000000000..98c114cd5 --- /dev/null +++ b/gpsbabel/testo.d/mtk_locus.test @@ -0,0 +1,9 @@ +# +# mtk_locus logger tests +# +FORMAT=mtk_locus + +rm -f ${TMPDIR}/$FORMAT.* + +gpsbabel -i $FORMAT -f ${REFERENCE}/$FORMAT.nmea -o gpx -F ${TMPDIR}/$FORMAT.gpx >/dev/null +compare ${TMPDIR}/$FORMAT.gpx ${REFERENCE}/$FORMAT.gpx diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c index 446170a08..f765778d6 100644 --- a/gpsbabel/vecs.c +++ b/gpsbabel/vecs.c @@ -87,6 +87,7 @@ extern ff_vecs_t mtk_vecs; extern ff_vecs_t mtk_fvecs; extern ff_vecs_t mtk_m241_vecs; extern ff_vecs_t mtk_m241_fvecs; +extern ff_vecs_t mtk_locus_vecs; extern ff_vecs_t navicache_vecs; extern ff_vecs_t netstumbler_vecs; extern ff_vecs_t nmea_vecs; @@ -502,6 +503,12 @@ vecs_t vec_list[] = { "Holux M-241 (MTK based) Binary File Format", "bin" }, + { + &mtk_locus_vecs, + "mtk_locus", + "MediaTek Locus", + NULL + }, #endif // MAXIMAL_ENABLED { &wbt_svecs, diff --git a/gpsbabel/xmldoc/formats/options/mtk_locus-baudrate.xml b/gpsbabel/xmldoc/formats/options/mtk_locus-baudrate.xml new file mode 100644 index 000000000..d1adfdf38 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/mtk_locus-baudrate.xml @@ -0,0 +1,2 @@ +The default is to autodetect the baudrate, but that can take a few seconds. If you know the baudrate of the device it is faster to specify it explicitly. +Only valid when using a USB device as input. diff --git a/gpsbabel/xmldoc/formats/options/mtk_locus-download.xml b/gpsbabel/xmldoc/formats/options/mtk_locus-download.xml new file mode 100644 index 000000000..0e0eb2460 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/mtk_locus-download.xml @@ -0,0 +1,5 @@ +This option processes a set of Locus fixes, by downloading it from an +attached USB device or by reading records stored in a normal file. +You might want to disable this option if all you want to do is erase the memory +or display the device status. Downloading a large dataset can take several minutes +and while that is happening no other device commands can be executed. \ No newline at end of file diff --git a/gpsbabel/xmldoc/formats/options/mtk_locus-enable.xml b/gpsbabel/xmldoc/formats/options/mtk_locus-enable.xml new file mode 100644 index 000000000..3f9e00b17 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/mtk_locus-enable.xml @@ -0,0 +1,2 @@ +This option sets logging on the device to on or off. Setting the logging off does not erase the saved fixes. +Only valid when using a USB device as input. diff --git a/gpsbabel/xmldoc/formats/options/mtk_locus-erase.xml b/gpsbabel/xmldoc/formats/options/mtk_locus-erase.xml new file mode 100644 index 000000000..3f4ecfacf --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/mtk_locus-erase.xml @@ -0,0 +1,2 @@ +This option erases the track log from the device after download. +Only valid when using a USB device as input. diff --git a/gpsbabel/xmldoc/formats/options/mtk_locus-status.xml b/gpsbabel/xmldoc/formats/options/mtk_locus-status.xml new file mode 100644 index 000000000..08b02d4d2 --- /dev/null +++ b/gpsbabel/xmldoc/formats/options/mtk_locus-status.xml @@ -0,0 +1,2 @@ +This option displays the status of the device after the download is complete. Status includes firmware version, number of log records in memory, interval between fixes, etc. +Only valid when using a USB device as input. \ No newline at end of file -- 2.30.2